home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)procdemo.c V1.23 3/17/95";
- #endif
-
- /*
- | file name - procdemo.c
- |===================================================================
- |
- | copyright (c) 1986
- | V. I. Corporation
- |
- |===================================================================
- |
- | module description/function:
- |
- | demonstrates use of DVtools subroutines for a process
- | application.
- |
- | This program can be linked to run:
- | With 100% CPU usage (which shows updates in a tight loop)
- | With Xt-base Time-Outs (which show update based on a timer.
- |
- | Set DV_RUNNING_IN_X according to the comments below.
- |
- | If the program is compiled to run in X, the optional arguments are:
- |
- | <time-out rate in milliseconds> The default is 100
- | <top view name> The default is top.v
- |
- | Other wise the optional arguments are:
- |
- | <device name> The default is NULL.
- | <top view name> The default is top.v
- |
- |===================================================================
- */
-
- #include "std.h"
- #include "dvstd.h"
- #include "VOstd.h"
- #include "dvtools.h"
- #include "Tfundecl.h"
- #include "VOfundecl.h"
- #include "VTfundecl.h"
- #include "VUfundecl.h"
- #include "VGfundecl.h"
- #include "GRfundecl.h"
- #include "prc_fundecl.h"
- #include "MISCfuns.h"
-
- #ifdef WINNT
- #include <windows.h>
- #endif /* WINNT */
-
-
- #define MAXNAMELEN 256
- #define DEF_COLORTAB (CHAR*)NULL
- #define DEF_PATH (CHAR*)NULL
- #define DEF_DISPTAB (CHAR*)NULL
-
- /* This program can be linked to run:
- |
- | With 100% CPU usage (which shows updates in a tight loop)
- | comment #define DV_USE_TIMER
- | With Xt-base Time-Outs (which show update based on a timer.
- | uncomment #define DV_USE_TIMER
- */
- #define DV_USE_TIMER
-
-
- /* Set the DV_RUNNNG_IN_X flag based on the -D compile option */
- #ifdef DV_NOT_USING_TIMER
- #undef DV_USE_TIMER
- #endif
-
- #ifdef DV_USE_TIMER
-
- LOCAL INT TimeoutInterval = 100;
- long updating=0; /* prevent timer from updating screen too often */
- #ifdef WINNT
-
-
- LOCAL HWND Hwnd;
- LOCAL VOID CALLBACK TimeOutProc V_P_((HWND hwnd,
- UINT uMsg,
- UINT idEvent,
- DWORD dwTime));
-
- #else /* UNIX */
- /* Include the X based files so we can add AppTimeOuts */
- #ifdef CONST
- #undef CONST
- #endif
-
- #ifndef __STDC__
- #define _NO_PROTO
- #endif
-
- /*
- * X11 include files
- */
- #include <X11/Xlib.h>
- #include <X11/Intrinsic.h>
-
- LOCAL XtAppContext app_context;
- LOCAL void UpdateProc V_P_((ADDRESS args, XtIntervalId *interval_id));
-
- #endif /* WINNT */
- #endif /* DV_USE_TIMER */
-
- /*
- * Define a data structure for storing the view information. These
- * structures will be stored in a symbol table.
- */
- typedef struct infostruct
- {
- VIEW view; /* The loaded view */
- DRAWPORT drawport; /* The drawport, if required */
- struct infostruct *previous_info; /* Previous view in chain */
- OBJECT holding_obj; /* The holding tank object */
- OBJECT reaction_obj; /* The reaction tank object */
- RECTANGLE holding_rect; /* Screen area for holding_obj */
- RECTANGLE reaction_rect; /* Screen area for reaction_obj */
- VIEW merge_view; /* View merged into */
- } VIEWINFO;
-
- /*
- * Global definition of the symbol table identifier.
- */
- LOCAL ADDRESS ViewSymTab;
-
- LOCAL OBJECT DVscreen;
- LOCAL VIEWINFO *current_info;
- LOCAL DV_BOOL QuitStatus = NO;
- LOCAL DV_BOOL TopViewDrawn = NO;
-
- /***************** Begin Function Declarations *************/
- LOCAL void UpdateDisplay V_P_((void));
- LOCAL void HandlePick V_P_((OBJECT location, int key, int button_num));
- LOCAL void QuitProgram V_P_((void));
- LOCAL void LoadSymbolTable V_P_((OBJECT screen, char *filename));
- LOCAL ADDRESS AddSubViews V_P_((OBJECT object, char *name, OBJECT screen));
- LOCAL VIEWINFO *DrawNewView V_P_((VIEWINFO *current, char *object_name));
- LOCAL void DrawMergedDrawing V_P_((VIEWINFO *current, char *object_name));
- LOCAL void TurnValve V_P_((char *object_name, int key, int button_num));
- LOCAL void SetTankRectangles V_P_((VIEWINFO *info));
- LOCAL void ChangeRectangle V_P_((DRAWPORT drawport, OBJECT object, RECTANGLE *rect));
- LOCAL void GetFilename V_P_((char *name, char *filename));
- LOCAL VIEWINFO *CreateViewRecord V_P_((void));
- LOCAL void ExciseAllMergedDrawings V_P_((VIEWINFO *current_info));
- LOCAL VIEWINFO *GetViewRecord V_P_((ADDRESS SymTab, char *key));
- LOCAL ADDRESS GetTankRectangles V_P_((OBJECT object, char *name, VIEWINFO *viewinfo));
- LOCAL void CleanUp V_P_((void));
- LOCAL ADDRESS RebindVdps V_P_((OBJECT vd_obj, ADDRESS vdp, ADDRESS args));
- LOCAL OBJECT GetSubObj V_P_((OBJECT object, int type));
- LOCAL ADDRESS GetObjHelper V_P_((OBJECT object, int *type));
- /***************** End Function Declarations *************/
-
- /* --------------------------------------------------------------- */
-
-
- /*
- * Main Program
- */
- #ifdef WINNT
- int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpCmdLine, int nCmdShow )
- {
- OBJECT location;
- CHAR *device = NULL;
- CHAR *top_view = "top.v";
- INT button_num;
- INT argc = 0;
- CHAR **argv;
- int error_code;
- char buf[50];
-
- make_argv(&argc,&argv,GetCommandLine());
-
- #else /* Not WINNT */
- int
- main (argc, argv)
- int argc;
- char *argv[];
- {
- OBJECT location;
- CHAR *device = NULL;
- CHAR *top_view = "top.v";
- INT button_num;
- int error_code;
- #endif /* WINNT */
-
-
- /*
- * Check if the display device is on the command line.
- */
- if (argc > 1)
- #ifdef DV_USE_TIMER
- TimeoutInterval = atoi (argv[1]);
- #else
- device = argv[1];
- #endif
-
- /*
- * Check if the top view name is on the command line.
- */
- if (argc > 2)
- top_view = argv[2];
-
- /*
- * Initialize the DV-Tools environment and open the graphics
- * device.
- */
- VUoff_copyright ();
- (VOID) TInit (DEF_PATH, DEF_DISPTAB);
- DVscreen = TscOpenSet (device, DEF_COLORTAB,
- V_WINDOW_NAME, "DataViews Process Control Demo",
- #ifdef WINNT
- V_WIN32_ICON_NAME, "procicon",
- #ifdef DOUBLE_BUFFER
- V_WIN32_DOUBLE_BUFFER, YES,
- #endif /* DOUBLE_BUFFER */
- #else /* Not WINNT */
- V_X_EXPOSURE_BLOCK, YES,
- #endif /* WINNT */
- V_INITIAL_CURSOR,
- V_END_OF_LIST);
-
- if(!DVscreen)
- {
- error_code=TscOpenError();
- #ifdef WINNT
- sprintf(buf,"Product is not validated. Error code %d.",error_code);
- MessageBox(NULL,buf,"Validation Error",MB_OK);
- #else
- fprintf(stderr,"Product is not validated. Error code %d.",error_code);
- #endif
- exit(error_code);
- }
-
- /* Setup the window events */
- (VOID) VOscWinEventMask ((ULONG) (V_KEYPRESS |
- V_BUTTONPRESS |
- V_RESIZE | V_EXPOSE |
- V_WINDOW_QUIT),
- (ULONG) V_END_OF_LIST);
-
- #ifdef DV_USE_TIMER
- #ifdef WINNT
- /* Get the Windows based information */
- (VOID) GRget (V_WIN32_WINDOW_HANDLE, &Hwnd, V_END_OF_LIST);
-
- /* Post a timeout for dynamic updates
- | The timeout procedure will update the dynamics of
- | all screens which have been opened. The procedure is invoked
- | whenever the specified time interval elapses. The interval is
- | specified in milliseconds.
- */
- SetTimer (Hwnd, (UINT)Hwnd, TimeoutInterval, (TIMERPROC)TimeOutProc);
- #else /* WINNT */
- /* Extract the X information so we can setup a Time-Out Proc
- | for updating....
- | Get the Xt Application Context information.
- | Post a timeout procedure will update the dynamics of
- | all screens which have been opened. The procedure is invoked
- | whenever the specified time interval elapses. The interval is
- | specified in milliseconds.
- */
- (VOID) GRget (V_X_APPLIC_CONTEXT, &app_context, V_END_OF_LIST);
- XtAppAddTimeOut (app_context, TimeoutInterval,
- (XtTimerCallbackProc) UpdateProc, NULL);
-
- #endif /* WINNT */
- #endif /* DV_USE_TIMER */
-
- /*
- * Initialize the data model.
- */
- MDLinit ();
-
- /*
- * Load all views into the symbol table and get the node for the
- * initial view. It draws the top view, before loading additional
- * views;
- */
- LoadSymbolTable (DVscreen, top_view);
- current_info = GetViewRecord (ViewSymTab, top_view);
-
- /* Now that we are ready, reset the cursor */
- (VOID) GRset (V_ACTIVE_CURSOR, V_END_OF_LIST);
-
- while (QuitStatus == NO)
- {
-
- #ifdef DV_USE_TIMER
-
- /* Get the Event, The, TimeOut Proc will Update the Display */
- location = VOloWinEventPoll (V_WAIT);
- #else
-
- /* Update the Display */
- UpdateDisplay ();
-
- /* Get the Event */
- location = VOloWinEventPoll (V_NO_WAIT);
-
-
- #endif
-
- if (location)
- {
-
- /*
- * Get the key/mouse press. If the key is the middle mouse button,
- * then extract all drawings that have been merged into the
- * current view. Otherwise get the selected named object
- * if there is one.
- */
- switch (VOloType (location))
- {
- case V_EXPOSE:
- if ( updating <= 0)
- {
- updating++;
- (VOID) TscRedraw (DVscreen, VOloRegion (location));
- updating--;
-
- }
- break;
- case V_RESIZE:
- if ( updating <= 0 )
- {
- updating++;
- (VOID) TscReset (DVscreen);
- updating--;
- }
- break;
- case V_WINDOW_QUIT:
- QuitStatus = YES;
- break;
- case V_KEYPRESS:
- HandlePick (location, VOloKey (location), 0);
- break;
- case V_BUTTONPRESS:
- button_num = VOloButton (location);
- switch (button_num)
- {
- case 1:
- case 3:
- HandlePick (location, 0, button_num);
- break;
- case 2:
- ExciseAllMergedDrawings (current_info);
- break;
- default:
- break;
- break;
- }
- }
- }
- }
-
- QuitProgram ();
-
- return (EXIT_OK);
- }
-
- #ifdef DV_USE_TIMER
- #ifdef WINNT
- /*ARGSUSED*/
- LOCAL VOID CALLBACK
- TimeOutProc (hwnd, uMsg, idEvent, dwTime)
- HWND hwnd;
- UINT uMsg;
- UINT idEvent;
- DWORD dwTime;
- {
- updating++;
- if ( updating == 1)
- UpdateDisplay ();
- updating--;
- }
-
- #else /* UNIX */
- /*ARGSUSED*/
- LOCAL void
- UpdateProc (args, interval_id)
- ADDRESS args;
- XtIntervalId *interval_id;
- {
-
- /* Update the current View */
- UpdateDisplay ();
-
- /* Re-Post the Time-Out */
- XtAppAddTimeOut (app_context, TimeoutInterval,
- (XtTimerCallbackProc) UpdateProc, NULL);
- }
-
- #endif /* WINNT */
- #endif /* DV_USE_TIMER */
-
- LOCAL void UpdateDisplay
- V_P_ ((void))
- {
- /*
- * Update the data model to get the next data iteration, adjust
- * the tank objects, and update all other dynamic portions
- * of the current view.
- */
- MDLupdate ();
- SetTankRectangles (current_info);
- (VOID) TdpDrawNext (current_info->drawport);
- }
-
- LOCAL void
- HandlePick (location, key, button_num)
- OBJECT location;
- int key;
- int button_num;
- {
- CHAR *object_name;
-
- if ((object_name = TloGetSelectedObjectName (location)))
- {
- /*
- * If the object name begins with an 'r', then this may be an
- * indicator of a view to replace the current one. If it
- * begins with an 'm', it may be a view to merge with the
- * current one. If it begins with a 'v' the this may be a
- * valve being turned.
- */
- if (*object_name == 'r')
- current_info = DrawNewView (current_info, object_name);
- else if (*object_name == 'm')
- DrawMergedDrawing (current_info, object_name);
- else if (*object_name == 'v') /* a valve has been found */
- TurnValve (object_name, key, button_num);
-
- /*
- * If the object name begins with a 'c', then this may be a
- * command to be performed. The only current command is
- * 'return' which means to return to the previous view.
- * If there is no previous view, then break out of the loop
- * and exit the program.
- */
- else if (*object_name == 'c') /* a command: */
- if (strcmp (object_name, "c:return") == 0)
- if (current_info->previous_info == NULL)
- /* We're at the top so QUIT */
- QuitStatus = YES;
- else
- {
- (VOID) TdpErase (current_info->drawport);
- current_info = current_info->previous_info;
- (VOID) TdpDraw (current_info->drawport);
- }
- }
- }
-
-
- LOCAL void QuitProgram
- V_P_ ((void))
- {
- /*
- * When we're done, erase the screen, clean up the memory
- * we've allocated, and close the graphics device.
- */
- CleanUp ();
- (VOID) TscClose (DVscreen);
- (VOID) TTerminate ();
- S_EXIT (0);
- }
-
-
- /* --------------------------------------------------------------- */
-
-
- /*
- * LoadSymbolTable -- creates the symbol table, enters the first
- * node, and then looks object names indicating that other views
- * should be loaded in. Also, checks for tank objects that need
- * to be treated seperately.
- */
- LOCAL void
- LoadSymbolTable (screen, filename)
- OBJECT screen;
- char *filename;
- {
- OBJECT drawing;
- VIEWINFO *viewinfo;
-
- /*
- * Create the symbol table.
- */
- ViewSymTab = VTstcreate ("View Information", (VTSTCOMPAREFUNPTR)NULL);
-
- /*
- * Make a new node containing the initial view, its drawport,
- * and the tank object information. Also, rebind all of this
- * view's variable descriptors. Enter this node into the
- * symbol table.
- */
- viewinfo = CreateViewRecord ();
- viewinfo->view = TviLoad (filename);
- viewinfo->drawport = TdpCreate (screen, viewinfo->view,
- (RECTANGLE *) NULL, (RECTANGLE *) NULL);
- drawing = TviGetDrawing (viewinfo->view);
- (VOID) TobForEachVdp (drawing, RebindVdps, (ADDRESS) NULL);
- (VOID) TdrForEachNamedObject (drawing,
- (TDRFOREACHNAMEDOBJFUNPTR) GetTankRectangles,
- (ADDRESS) viewinfo);
- (VOID) VTstsninsert (ViewSymTab, StrClone (filename), (INT *) viewinfo);
-
- /* If top view... Draw it */
- if (TopViewDrawn == NO)
- {
- /*
- * Adjust the size of the tank objects if necessary, and draw the
- * initial view.
- */
- SetTankRectangles (viewinfo);
- (VOID) TdpDraw (viewinfo->drawport);
- TopViewDrawn = YES;
- }
-
- /*
- * Search this view for object names refering to other views that
- * also need to be loaded into the symbol table.
- */
- (VOID) TdrForEachNamedObject (drawing,
- (TDRFOREACHNAMEDOBJFUNPTR) AddSubViews,
- (ADDRESS) screen);
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * AddSubViews -- recursively searches for all other needed
- * views and and loads them into the symbol table.
- */
- /*ARGSUSED*/
- LOCAL ADDRESS
- AddSubViews (object, name, screen)
- OBJECT object;
- char *name;
- OBJECT screen;
- {
- CHAR filename[MAXNAMELEN];
- OBJECT drawing;
- VIEW view;
- VIEWINFO *viewinfo;
-
- /*
- * If the current object name begins with an 'r' or an 'm' then
- * name might refer to a view to be loaded.
- */
- if (*name == 'r' || *name == 'm')
- {
-
- /*
- * Extract the filename from the object name, make sure it hasn't
- * already been loaded, and attempt to load the file as a view.
- */
- GetFilename (name, filename);
- if (!VTstkeyfind (ViewSymTab, filename))
- /* if not already loaded */
- if ((view = TviLoad (filename)))
- {
-
- /*
- * Create a new symbol table node for the view, possibly
- * making a drawport for it, otherwise setting the drawing
- * part to have no background color (this is necessary
- * to be able to draw the drawing as a unit without it
- * trying to erase the entire drawport in its background
- * color). Save the new node in the symbol table.
- */
- viewinfo = CreateViewRecord ();
- viewinfo->view = view;
- drawing = TviGetDrawing (view);
- if (*name == 'r')
- viewinfo->drawport = TdpCreate (screen, view,
- (RECTANGLE *) NULL,
- (RECTANGLE *) NULL);
- else
- (VOID) VOdrBackcolor (drawing, (OBJECT) NO_BACKGROUND);
- (VOID) TdrForEachNamedObject (drawing,
- (TDRFOREACHNAMEDOBJFUNPTR)
- GetTankRectangles,
- (ADDRESS) viewinfo);
- (VOID) VTstsninsert (ViewSymTab, StrClone (filename),
- (INT *) viewinfo);
-
- /*
- * Rebind all variable descriptors in this view and continue
- * to search recursively for other views to be loaded.
- */
- (VOID) TobForEachVdp (drawing, RebindVdps, (ADDRESS) NULL);
- (VOID) TdrForEachNamedObject (drawing,
- (TDRFOREACHNAMEDOBJFUNPTR)
- AddSubViews,
- (ADDRESS) screen);
- }
- }
-
- return NULL;
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * DrawNewView -- switches from the current view to a new view
- * specified by the object name parameter.
- */
- LOCAL VIEWINFO *
- DrawNewView (current, object_name)
- VIEWINFO *current;
- char *object_name;
- {
- CHAR filename[MAXNAMELEN];
- VIEWINFO *new_info;
-
- /*
- * Get the file name from the object name and see if the view
- * is stored in the symbol table.
- */
- GetFilename (object_name, filename);
- if ((new_info = GetViewRecord (ViewSymTab, filename)))
- {
-
- /*
- * Save the current information to return to when the user
- * selects the return area.
- */
- new_info->previous_info = current;
-
- /*
- * If there are tank objects in the new view, then reset their
- * variable descriptors to force them to be drawn correctly.
- */
- if (new_info->holding_obj)
- VOvdReset (GetSubObj (new_info->holding_obj, OT_VD));
- if (new_info->reaction_obj)
- VOvdReset (GetSubObj (new_info->reaction_obj, OT_VD));
-
- /*
- * Erase the current drawport and draw the new one after
- * manipulating the tank objects. Return a pointer to the
- * new information. If the object name didn't match any in
- * the symbol table return a pointer to the current
- * information.
- */
- (VOID) TdpErase (current->drawport);
- SetTankRectangles (new_info);
- (VOID) TdpDraw (new_info->drawport);
- return new_info;
- }
- else
- return current;
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * DrawMergedDrawing -- merges another drawing into the current
- * view according to the object name parameter.
- */
- LOCAL void
- DrawMergedDrawing (current, object_name)
- VIEWINFO *current;
- char *object_name;
- {
- CHAR filename[MAXNAMELEN];
- VIEWINFO *new_info;
- OBJECT drawing;
-
- /*
- * Get the file name from the object name and see if the view is
- * stored in the symbol table.
- */
- GetFilename (object_name, filename);
- if ((new_info = GetViewRecord (ViewSymTab, filename)))
- {
-
- /*
- * Get the drawing object from the view. If the drawing is
- * already merged into the current view, then excise the
- * drawing and erase it. Otherwise, merge the drawing into
- * the current view and draw it.
- */
- drawing = TviGetDrawing (new_info->view);
- if (new_info->merge_view)
- {
- (VOID) TdpEraseObject (current->drawport, drawing);
- (VOID) TviExciseDrawing (current->view, drawing);
- new_info->merge_view = NULL;
- }
- else
- {
- (VOID) TviMergeDrawing (current->view, drawing);
- new_info->merge_view = current->view;
- (VOID) TdpDrawObject (current->drawport, drawing);
- }
- }
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * TurnValve -- modifies the data model by changing the value of
- * one of the valves.
- */
- LOCAL void
- TurnValve (object_name, key, button_num)
- char *object_name;
- int key;
- int button_num;
- {
- INT change = 0;
-
- if (key == 'o' || key == 'O' || button_num == 1)
- change = 1;
- if (key == 'c' || key == 'C' || button_num == 3)
- change = -1;
- MDLchangevalve (object_name, change);
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * SetTankRectangles -- changes the size and redraws the tank
- * objects in the current view, if they exist.
- */
- LOCAL void
- SetTankRectangles (info)
- VIEWINFO *info;
- {
- /*
- * If each tank exists, then update each rectangle.
- */
- if (info->holding_obj)
- ChangeRectangle (info->drawport, info->holding_obj,
- &info->holding_rect);
- if (info->reaction_obj)
- ChangeRectangle (info->drawport, info->reaction_obj,
- &info->reaction_rect);
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * ChangeRectangle -- changes the size of a rectangle according to
- * an existing variable descriptor. The color of the rectangle is
- * also taken into account. The routine redraws the rectangle if
- * possible and/or necessary.
- */
- LOCAL void
- ChangeRectangle (drawport, object, rect)
- DRAWPORT drawport;
- OBJECT object;
- RECTANGLE *rect;
- {
- ADDRESS vdp;
- OBJECT vd_obj;
- FLOAT *dataptr;
- FLOAT size;
- DOUBLE minval, maxval;
- OBJECT point1, point2;
- DV_POINT pt1, pt2, dummy;
- DV_BOOL color_changed = NO;
- INT newy;
-
-
- /*
- * Get the variable descriptor subobject for the object. Then, get
- * the actual variable descriptor and the address of the data
- * buffer used by the variable descriptor. The buffer should
- * point to two floating point values, the first of which
- * controls the color dynamics of the object, and the second
- * of which we'll use to control the size of the rectangle.
- */
- vd_obj = GetSubObj (object, OT_VD);
- vdp = VOvdAddress (vd_obj);
- dataptr = (FLOAT *) MDLget_buffer (vdp);
- size = *(++dataptr);
-
- /*
- * Get the range of the variable descriptor and use it to compute
- * the new y position of the upper left corner of the rectangle.
- */
- VGvd_drange (vdp, &minval, &maxval);
- size = (FLOAT)S_MIN (size, maxval);
- size = (FLOAT)S_MAX (size, minval);
- size = (FLOAT)((size - minval) / (maxval - minval));
- newy = (INT)(rect->ll.y + (rect->ur.y - rect->ll.y) * size);
-
- /*
- * Get the control points of the rectangle and the world coordinate
- * positions they represent.
- */
- point1 = VOobPtGet (object, 1);
- point2 = VOobPtGet (object, 2);
- VOptGet (point1, &pt1, &dummy);
- VOptGet (point2, &pt2, &dummy);
-
- /*
- * Check to see if the color of the rectangle should change.
- */
- if (VOvdChanged (vd_obj))
- color_changed = YES;
-
- /*
- * If the drawport hasn't been drawn yet, just move the control
- * point.
- */
- if (!TdpIsDrawn (drawport))
- VOptMove (point2, 'A', (INT) pt2.x, newy);
-
- /*
- * If the color hasn't changed and the rectangle is bigger,
- * then draw the entire rectangle over.
- */
- else if (!color_changed && (newy > pt2.y))
- {
- VOptMove (point2, 'A', (INT) pt2.x, newy);
- (VOID) TdpDrawObject (drawport, object);
- }
-
- /*
- * If the color hasn't changed and the rectangle is smaller,
- * then move the bottom control point up and just erase the top
- * part. Then move the bottom control point back and move the
- * top control point down to the correct position.
- */
- else if (!color_changed && (newy < pt2.y))
- {
- VOptMove (point1, 'A', (INT) pt1.x, newy);
- (VOID) TdpEraseObject (drawport, object);
- VOptMove (point1, 'A', (INT) rect->ll.x, (INT) rect->ll.y);
- VOptMove (point2, 'A', (INT) pt2.x, newy);
- }
-
- /*
- * If the color has changed, then redraw the rectangle, erasing the
- * old one only if the size has also changed.
- */
- else if (color_changed)
- {
- if (newy != pt2.y)
- {
- (VOID) TdpEraseObject (drawport, object);
- VOptMove (point2, 'A', (INT) pt2.x, newy);
- }
- (VOID) TdpDrawObject (drawport, object);
- }
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * GetFilename -- finds the file name portion of an object name and
- * adds a .v extension.
- */
- LOCAL void
- GetFilename (name, filename)
- char *name;
- char *filename;
- {
- CHAR *ptr;
- INT length;
-
- /*
- * Find the ':' delimeter and set the pointer to the next position.
- */
- for (ptr = name; *ptr != ':'; ptr++)
- ;
-
- ptr++;
-
- /*
- * Copy the rest of the string into the destination and then
- * copy the extension.
- */
- length = strlen (ptr);
- memcpy(filename, ptr, (unsigned)length);
- memcpy(&filename[length], ".v", 5);
- }
-
-
- /* --------------------------------------------------------------- */
-
-
- /*
- * CreateViewRecord -- creates and initializes a view record to be
- * used in the symbol table.
- */
- LOCAL VIEWINFO *CreateViewRecord
- V_P_ ((void))
- {
- VIEWINFO *record;
-
- /*
- * Allocate a new block of dynamic memory of the correct size --
- * we need to remember to free this when we're finished with it.
- */
- record = (VIEWINFO *) S_ALLOC ((LONG) sizeof (VIEWINFO));
-
- record->view = NULL;
- record->drawport = NULL;
- record->merge_view = NULL;
- record->previous_info = NULL;
- record->holding_rect.ll.x = record->holding_rect.ll.y =
- record->holding_rect.ur.x = record->holding_rect.ur.y = 0;
- record->reaction_rect.ll.x = record->reaction_rect.ll.y =
- record->reaction_rect.ur.x = record->reaction_rect.ur.y = 0;
- record->holding_obj = 0;
- record->reaction_obj = 0;
-
- return record;
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * ExciseAllMergedDrawings -- finds all drawing that are merged
- * into current drawing, excising them and erasing them.
- */
- LOCAL void
- ExciseAllMergedDrawings (current_info)
- VIEWINFO *current_info;
- {
- INT i;
- VIEWINFO *info;
- OBJECT drawing;
-
- /*
- * Traverse the symbol table looking for drawings that are merged
- * into the current view.
- */
- for (i = 0; i < (VTstlen (ViewSymTab) - 1); i++)
- {
- info = (VIEWINFO *) VTsnvalue (VTstsnget (ViewSymTab, i));
- if (info->merge_view == current_info->view)
- {
-
- /*
- * Excise each drawing that we find, erase it, and clear the
- * correct fields in the record.
- */
- drawing = TviGetDrawing (info->view);
- (VOID) TviExciseDrawing (current_info->view, drawing);
- (VOID) TdpEraseObject (current_info->drawport, drawing);
- info->merge_view = NULL;
- }
- }
- }
-
-
- /* -------------------------------------------------------------- */
-
-
- /*
- * GetViewRecord -- performs symbol table lookup based on the key
- * value.
- */
- LOCAL VIEWINFO *
- GetViewRecord (SymTab, key)
- ADDRESS SymTab;
- char *key;
- {
- return (VIEWINFO *) VTsnvalue (VTstkeyfind (SymTab, key));
- }
-
-
- /* ----------------------------------------------------------------- */
-
-
- /*
- * GetTankRectangles -- Finds the tank objects in the current view
- * and saves some information associated with them.
- */
- /*ARGSUSED*/
- LOCAL ADDRESS
- GetTankRectangles (object, name, viewinfo)
- OBJECT object;
- char *name;
- VIEWINFO *viewinfo;
- {
- OBJECT pt1, pt2;
- DV_POINT dummy;
- OBJECT vd_obj;
- ADDRESS vdp;
-
- /*
- * If the object isn't dynamic, its not one we're looking for.
- */
- if (!(vd_obj = GetSubObj (object, OT_VD)))
- return NULL;
-
- /*
- * Get the variable descriptor and use its name to see if this
- * object is one we're interested in. If it is, get the world
- * coordinate values of its control points and also save the
- * object identifier.
- */
- vdp = VOvdAddress (vd_obj);
- if (strcmp (VGvdvarname (vdp), "hold_tmp_vol") == 0)
- {
- pt1 = VOobPtGet (object, 1);
- pt2 = VOobPtGet (object, 2);
- VOptGet (pt1, &viewinfo->holding_rect.ll, &dummy);
- VOptGet (pt2, &viewinfo->holding_rect.ur, &dummy);
- viewinfo->holding_obj = object;
- }
- else if (strcmp (VGvdvarname (vdp), "reac_tmp_vol") == 0)
- {
- pt1 = VOobPtGet (object, 1);
- pt2 = VOobPtGet (object, 2);
- VOptGet (pt1, &viewinfo->reaction_rect.ll, &dummy);
- VOptGet (pt2, &viewinfo->reaction_rect.ur, &dummy);
- viewinfo->reaction_obj = object;
- }
-
- return NULL;
- }
-
-
- /* ----------------------------------------------------------------- */
-
-
- /*
- * CleanUp -- clean up the symbol table, freeing all previously
- * allocated dynamic memory.
- */
- LOCAL void CleanUp
- V_P_ ((void))
- {
- INT i;
- VIEWINFO *info;
- OBJECT drawing;
-
- /*
- * Traverse the symbol table finding and excising all merged
- * drawings. This is necessary to keep the keep the reference
- * counts consistent from view to view.
- */
- for (i = 0; i < (VTstlen (ViewSymTab) - 1); i++)
- {
- info = (VIEWINFO *) VTsnvalue (VTstsnget (ViewSymTab, i));
- if (info->merge_view)
- {
- drawing = TviGetDrawing (info->view);
- (VOID) TviExciseDrawing (info->merge_view, drawing);
- }
- }
-
- /*
- * Traverse the symbol table again, removing each node as we go,
- * destroying drawports if they exist and destroying each view.
- * Also, free the memory we allocated for each record.
- */
- while (VTstlen (ViewSymTab) > 0)
- {
- info = (VIEWINFO *) VTsnvalue (VTstsnget (ViewSymTab, 0));
- VTstsnremove (ViewSymTab, VTstsnget (ViewSymTab, 0));
- if (info->drawport)
- (VOID) TdpDestroy (info->drawport);
- (VOID) TviDestroy (info->view);
- S_FREE ((ADDRESS) info);
- }
-
- /*
- * Finally, destroy the symbol table.
- */
- VTstdestroy (ViewSymTab);
- }
-
-
- /* ----------------------------------------------------------------- */
-
-
- /*
- * RebindVdps -- rebinds all variable descriptors in a view that
- * are recognized by the underlying data model.
- */
- /*ARGSUSED*/
- LOCAL ADDRESS
- RebindVdps (vd_obj, vdp, args)
- OBJECT vd_obj;
- ADDRESS vdp;
- ADDRESS args;
- {
- ADDRESS buffer;
-
- buffer = MDLget_buffer (vdp);
- if (buffer)
- (VOID) TvdPutBuffer (vdp, buffer);
-
- return NULL;
- }
-
-
- /* ----------------------------------------------------------------- */
-
-
- /*
- * GetSubObj -- gets the first subobject of a given type of an
- * object.
- */
- LOCAL OBJECT
- GetSubObj (object, type)
- OBJECT object;
- int type;
- {
-
- return (OBJECT) TobForEachSubobject (object,
- (TOBFOREACHSUBOBJFUNPTR) GetObjHelper,
- (ADDRESS) & type);
- }
-
-
- /*
- * GetObjHelper -- used by GetSubObj to traverse the subobjects
- * of an object, looking for a certain type.
- */
- LOCAL ADDRESS
- GetObjHelper (object, type)
- OBJECT object;
- int *type;
- {
- if (VOobType (object) == *type)
- return (ADDRESS) object;
- else
- return NULL;
- }
-
- /*==================================================================
- |
- | StrClone
- | Allocates space for and makes a copy of a specified string,
- | returning a pointer to the string. If there is no input
- | string, the routine returns a NULL.
- */
- CHAR *StrClone( str )
- CHAR *str;
- {
- FAST INT len;
- CHAR *newstr;
- FAST CHAR *to;
- FAST CHAR *from;
-
- if( str == NULL )
- return( NULL );
- len = S_STRLEN( str ) + 1;
- newstr = (CHAR *)S_ALLOC( len );
- if( newstr )
- for( to = newstr, from = str; len > 0; len-- )
- *to++ = *from++;
- return( newstr );
- }
-
-
-